Correlation is a measurement of how similar two signals. The cross correlation allows us to measure the similiarity between two signals at different lag positions.
In [1]:
# Sin function to generate signals
delay = 0.6 # ms
f = lambda(x) : np.sin(x) # original signal
g = lambda(x) : np.sin(x - delay) # introduce s delay
In [2]:
dt = 0.05 # sampling interval (in ms)
# to get a good estimation of the delay with cross correlation, you need many perdiods.
time = np.arange(start = 0, stop =30.00, step = dt) # sample 5 ms seconds at 20 kHz (100 samples)
# generate signals
A, B = f(time), g(time)
# Plot signals
plt.plot(time, A, lw=1, color = 'magenta');
plt.plot(time, B, lw=1, color = 'blue');
plt.xlabel('Time (ms)');
plt.ylabel('Signal (AU)');
In [3]:
# compute signal autocorrelation
coor = np.correlate(A, A, 'same')
maxlag = int(coor.size/2)
lag = np.arange(-maxlag, maxlag+coor.size%2)*dt
plt.plot(lag, coor, lw=1);
line = plt.axvline(x=0, ymin=-40, ymax = 50, linewidth=1.5, color='r')
line.set_dashes([8, 4, 2, 4, 2, 4])
In [4]:
# compute cross correlation
coor = np.correlate(A, B, 'same')
maxlag = int(coor.size/2)
lag = np.arange(-maxlag, maxlag + coor.size%2 )*dt
# plot cross correlogram with line in delay
plt.plot(lag, coor, lw=1);
line = plt.axvline(x=-delay, ymin=np.min(coor), ymax = np.max(coor), linewidth=1.5, color='r')
line.set_dashes([8, 4, 2, 4, 2, 4])
In [5]:
# Calculate lag position of maximal correlation
def lag_ix(x,y):
corr = np.correlate(x,y,mode='full')
pos_ix = np.argmax( np.abs(corr) )
lag_ix = pos_ix - (corr.size-1)/2
return lag_ix
lag_ix(A,B)
Out[5]:
In [6]:
delay_estimation = -lag_ix(A,B)*dt # in ms
delay_estimation
Out[6]:
In [7]:
plt.plot(lag, coor, lw=1);
line = plt.axvline(x=-delay_estimation, ymin=-40, ymax = 50,
linewidth=1.5, color='r', label='estimated delay')
line = plt.axvline(x=-delay, ymin=np.min(coor), ymax = np.max(coor),
linewidth=1.5, color='c', label='true delay')
line.set_dashes([8, 4, 2, 4, 2, 4])
plt.xlim(-1.5*delay, 0)
plt.legend(loc='lower right');
In [7]: